﻿using System;
using System.Diagnostics;
using TimeSnapperPluginAPI;
using System.Net;
using System.Xml;
using System.IO;

namespace SamplePlugins
{
    public class RssImporterPlugin : ITimeSnapperPlugin
    {
        private IServices m_services;
        System.Timers.Timer m_timer;

        string m_feedUrl;
        string m_username;
        string m_password;
        int m_flagColor;

        private const string cFeed = "RssImporterPlugin.Feed";
        private const string cUsername = "RssImporterPlugin.Username";
        private const string cPassword = "RssImporterPlugin.Password";
        private const string cFlagColor = "RssImporterPlugin.FlagColor";

        bool ITimeSnapperPlugin.Configurable
        {
            get { return true; }
        }

        void ITimeSnapperPlugin.Configure()
        {
            RssImporterConfigurationForm frm = new RssImporterConfigurationForm(m_services);

            frm.Feed = m_feedUrl;
            frm.Username = m_username;
            frm.Password = m_password;
            frm.FlagColor = m_flagColor;

            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                m_feedUrl = frm.Feed;
                m_username = frm.Username;
                m_password = frm.Password;

                m_services.SettingsServices.SetPropertyValue(cFeed, m_feedUrl);
                m_services.SettingsServices.SetPropertyValue(cUsername, m_username);
                m_services.SettingsServices.SetPropertyValue(cPassword, m_password);
                m_services.SettingsServices.SetPropertyValue(cFlagColor, m_flagColor.ToString());

                StartFeedPollingIfAllValid();
            }
        }

        string ITimeSnapperPlugin.Description
        {
            get 
            { 
                return "Creates flags on the TimeBar based on entries from an RSS feed (e.g. Twitter)."; 
            }
        }

        string ITimeSnapperPlugin.FriendlyName
        {
            get { return "RSS to Flags"; }
        }

        object ITimeSnapperPlugin.HandleEvent(TimeSnapperEvent timeSnapperEvent, IServices services, EventArgs args)
        {
            switch (timeSnapperEvent)
            {
                case TimeSnapperEvent.PluginsLoaded:
                    // start a timer for the processing
                    m_services = services;
                    m_feedUrl = services.SettingsServices.GetPropertyValue(cFeed, "");
                    m_username = services.SettingsServices.GetPropertyValue(cUsername, "");
                    m_password = services.SettingsServices.GetPropertyValue(cPassword, "");

                    int defaultColor = System.Drawing.Color.GreenYellow.ToArgb();
                    m_flagColor = int.Parse(services.SettingsServices.GetPropertyValue(cFlagColor,
                        defaultColor.ToString()));

                    StartFeedPollingIfAllValid();

                    // kick start it to get immediate results
                    timer_Elapsed(null, null);
                    break;
                default:
                    return null;
            }
            return null;
        }

        private void StartFeedPollingIfAllValid()
        {
            if (m_feedUrl != "" && Uri.IsWellFormedUriString(m_feedUrl, UriKind.Absolute))
            {
                // only start the timer if this is a well formed Uri
                if (m_timer == null)
                {
                    m_timer = new System.Timers.Timer();
                    m_timer.AutoReset = false;  // no autoreset because we don't want reentrant events
                    m_timer.Interval = 1000 * 60 * 30;  // 30 mins
                    m_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
                }
                m_timer.Start();
            }
            else
            {
                if (m_timer != null)
                {
                    m_timer.Stop();
                    m_timer.Dispose();
                    m_timer = null;
                }
            }
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            WebClient c = new System.Net.WebClient();
            c.DownloadDataCompleted += new System.Net.DownloadDataCompletedEventHandler(DownloadDataCompleted);

            if (m_username != "")
            {
                NetworkCredential nc = new NetworkCredential(m_username, m_password);
                c.Credentials = nc;
            }
            c.DownloadDataAsync(new Uri(m_feedUrl));
        }

        void DownloadDataCompleted(object sender, System.Net.DownloadDataCompletedEventArgs e)
        {
            try
            {
                if (e.Cancelled)
                    return;

                if (e.Error != null)
                {
                    // some error came up.  Log the error and the inner exception
                    m_services.Log(e.Error.Message);
                    if (e.Error.InnerException != null)
                        m_services.Log(e.Error.InnerException.Message);
                    return;
                }

                // all seeems to be good... do the actual processing
                string result = System.Text.Encoding.UTF8.GetString(e.Result);
                FlagHelpers.SaveFlagsFromRss(m_services, result, m_flagColor);
            }
            catch (XmlException xex)
            {
                Debug.WriteLine(xex.ToString());
            }
            finally
            {
                // we need to remember to start the timer back up again
                m_timer.Start();
            }
        }        
     
        TimeSnapperMenuItem[] ITimeSnapperPlugin.MenuItems()
        {
            return null;
        }

        Guid ITimeSnapperPlugin.PluginID
        {
            get { return new Guid("928B84EB-45D1-4076-8B59-A46044C44BAE"); }
        }

        TimeSnapperEvent[] ITimeSnapperPlugin.SubscribesTo()
        {
            return new TimeSnapperEvent[] { TimeSnapperEvent.PluginsLoaded };
        }
    }
}
